package com.zhdl.modules.assemblybolt;

import com.google.common.eventbus.Subscribe;
import com.project.common.util.DelayUtil;
import com.zhdl.common.eventbus.center.EventBusCenter;
import com.zhdl.modules.assemblybolt.web.req.AssemblyBoltData;
import com.zhdl.modules.assemblybolt.web.req.TransportScrewData;
import com.zhdl.modules.assemblybolt.service.AssemblyBoltService;
import com.zhdl.modules.tools.CommonCallback;
import com.zhdl.modules.tools.IntToHexUtil;
import com.zhdl.websocket.service.impl.WebSocketServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;

@Slf4j
@Component
public class TransportScrewNextProcess {
    @Resource
    public ThreadPoolTaskScheduler taskScheduler1;
    @Resource
    WebSocketServiceImpl webSocketService;
    Map<String, ScheduledFuture<?>> mapSF = new HashMap<>();
    /**
     * 运行状态
     */
    boolean isRunning = false;
    /**
     * 因时 以及 Micro串口
     */
    String microPort = "3", inspirePort = "7";
    /**
     * 每个轴实际数据
     */
    TransportScrewData transportScrewData = new TransportScrewData();
    public String PLCInfo;
    public int doneCount = 0;
    @Resource
    private AssemblyBoltService assemblyBoltService;

    public void init() {
        EventBusCenter.getEventBus().register(this);

        taskScheduler1.scheduleWithFixedDelay(() ->
                assemblyBoltService.readMotorAIDistance(1, s ->
                        log.info("测距测距---->" + s+">>>>>"+ IntToHexUtil.hexToFloat(s))), 1000);

    }
    @Subscribe
    public void onPLCInfo(AssemblyBoltData data) {
        PLCInfo = data.getSiemensValue0To404();
    }

    public boolean motorInitStatus = false;

    public void motorInit(){
        plcMotorRun(5, 200, 0, new CommonCallback<String>() {
            @Override
            public void statusCallback(String s) {

            }
        });
        DelayUtil.delayedExecution(2000, new Runnable() {
            @Override
            public void run() {
                plcMotorRun(4, 200, 0, new CommonCallback<String>() {
                    @Override
                    public void statusCallback(String s) {
                        plcMotorRun(6, 100, 0, new CommonCallback<String>() {
                            @Override
                            public void statusCallback(String s) {

                            }
                        });
                        S485MotorRun("3", 2, 3, 100, new CommonCallback<String>() {
                            @Override
                            public void statusCallback(String s) {

                            }
                        });
                        S485MotorRun("3", 2, 2, 100, new CommonCallback<String>() {
                            @Override
                            public void statusCallback(String s) {

                            }
                        });
                        DelayUtil.delayedExecution(1000, new Runnable() {
                            @Override
                            public void run() {
                                S485MotorRun("3", 2, 1, 100, new CommonCallback<String>() {
                                    @Override
                                    public void statusCallback(String s) {
                                        DelayUtil.delayedExecution(1000, new Runnable() {
                                            @Override
                                            public void run() {
                                                S485MotorRun("3", 2, 2, 100, new CommonCallback<String>() {
                                                    @Override
                                                    public void statusCallback(String s) {

                                                    }
                                                });
                                            }
                                        });
                                    }
                                });
                            }
                        });
                        S485MotorRun("3", 3, 2, 300, new CommonCallback<String>() {
                            @Override
                            public void statusCallback(String s) {
                                DelayUtil.delayedExecution(1000, new Runnable() {
                                    @Override
                                    public void run() {
                                        S485MotorRun("3", 3, 1, 300, new CommonCallback<String>() {
                                            @Override
                                            public void statusCallback(String s) {
                                                DelayUtil.delayedExecution(1000, new Runnable() {
                                                    @Override
                                                    public void run() {
                                                        S485MotorRun("3", 3, 2, 300, new CommonCallback<String>() {
                                                            @Override
                                                            public void statusCallback(String s) {

                                                            }
                                                        });
                                                    }
                                                });
                                            }
                                        });
                                    }
                                });
                            }
                        });

                        S485MotorRun("3", 1, 2, 300, new CommonCallback<String>() {
                            @Override
                            public void statusCallback(String s) {
                                DelayUtil.delayedExecution(1000, new Runnable() {
                                    @Override
                                    public void run() {
                                        S485MotorRun("3", 1, 4, 300, new CommonCallback<String>() {
                                            @Override
                                            public void statusCallback(String s) {
                                                DelayUtil.delayedExecution(1000, new Runnable() {
                                                    @Override
                                                    public void run() {
                                                        S485MotorRun("3", 1, 3, 300, new CommonCallback<String>() {
                                                            @Override
                                                            public void statusCallback(String s) {
                                                                S485MotorRun("3", 1, 1, 300, new CommonCallback<String>() {
                                                                    @Override
                                                                    public void statusCallback(String s) {
                                                                        DelayUtil.delayedExecution(1000, new Runnable() {
                                                                            @Override
                                                                            public void run() {
                                                                                S485MotorRun("3", 1, 4, 300, new CommonCallback<String>() {
                                                                                    @Override
                                                                                    public void statusCallback(String s) {
                                                                                        S485MotorRun("3", 1, 3, 300, new CommonCallback<String>() {
                                                                                            @Override
                                                                                            public void statusCallback(String s) {
                                                                                                motorInitStatus = true;
                                                                                                checkStart();
                                                                                            }
                                                                                        });
                                                                                    }
                                                                                });
                                                                            }
                                                                        });
                                                                    }
                                                                });
                                                            }
                                                        });
                                                    }
                                                });
                                            }
                                        });
                                    }
                                });
                            }
                        });
                        assemblyBoltService.plcSetMotorHomeTrig(8, new CommonCallback<String>() {
                            @Override
                            public void statusCallback(String s) {

                            }
                        });
                    }
                });
            }
        });

    }

    public void release() {
        isRunning = false;
    }

    public void startProcess() {
        if (isRunning) {
            return;
        }
        isRunning = true;

        if (!motorInitStatus){
            motorInit();
        } else {
            log.info("流程开始!!!!");
            checkStart();
        }

    }

    private void nextProcess(int process) {
        process++;
        switch (process) {
            case 1:
                /* 轴六 推杆 */
                plcMotorRun(6, 100, transportScrewData.getAxle6XDistance(), new CommonCallback<String>() {
                    @Override
                    public void statusCallback(String s) {
                        nextProcess(1);
                    }
                });
                break;
            case 2:
                /* 大夹具夹紧 */
                S485MotorRun(microPort, 3, 1, 500, new CommonCallback<String>() {
                    @Override
                    public void statusCallback(String s) {
                        nextProcess(2);
                    }
                });
                break;
            case 3:
                /* 轴六 回去 */
                plcMotorRun(6, 100, 0, new CommonCallback<String>() {
                    @Override
                    public void statusCallback(String s) {
                        log.info("");
                    }
                });
                /* 轴八运动到上方 */
                plcMotorRun(8, 200, transportScrewData.getAxle8ODistance(), new CommonCallback<String>() {
                    @Override
                    public void statusCallback(String s) {
                        nextProcess(3);
                    }
                });
                break;
            case 4:
                /* 轴五下降至 抓取点 */
                plcMotorRun(5, 200, transportScrewData.getAxle5_1Distance(), new CommonCallback<String>() {
                    @Override
                    public void statusCallback(String s) {
                        nextProcess(4);
                    }
                });
                break;

            case 5:
                /* 旋转 下压顶螺丝帽 */
                assemblyBoltService.plcControlMotorRunY(5,6.0f,-18);
                assemblyBoltService.plcControlMotorSerRun(5,true);
                S485MotorRun(microPort, 1, 3, 10, s -> {
                });
                S485MotorRun(microPort, 1, 2, 3000, s -> {
                    S485MotorRun(microPort, 1, 4, 100, s1 -> {
                        /* 小轴夹紧 */
                        S485MotorRun(microPort, 2, 1, 500, s2 -> nextProcess(5));
                    });
                });
                break;
            case 6:
                /* 大夹具松开 */
                S485MotorRun(microPort, 3, 2, 500, new CommonCallback<String>() {
                    @Override
                    public void statusCallback(String s) {
                        nextProcess(6);
                    }
                });
                break;
            case 7:
                /* 轴五 升起来 */
                plcMotorRun(5, 200, transportScrewData.getAxle5_2Distance(), new CommonCallback<String>() {
                    @Override
                    public void statusCallback(String s) {
                        nextProcess(7);
                    }
                });

                break;
            case 8:
                /* 轴八回去等待 */
                plcMotorRun(8, 200, 0, new CommonCallback<String>() {
                    @Override
                    public void statusCallback(String s) {
                        nextProcess(8);
                    }
                });
                break;

            case 9:
                /* 轴四 过去打胶 */
                plcMotorRun(4, 200, transportScrewData.getAxle4_1Distance(), new CommonCallback<String>() {
                    @Override
                    public void statusCallback(String s) {
                        nextProcess(9);
                    }
                });
                break;

            case 10:
                /* 控制打胶 */
                assemblyBoltService.writeMotorIOStatus(1, 1, new CommonCallback<Boolean>() {
                    @Override
                    public void statusCallback(Boolean aBoolean) {

                    }
                });
                DelayUtil.delayedExecution(200, new Runnable() {
                    @Override
                    public void run() {
                        /* 打两秒的胶 */
                        assemblyBoltService.writeMotorIOStatus(1, 0, new CommonCallback<Boolean>() {
                            @Override
                            public void statusCallback(Boolean aBoolean) {

                            }
                        });
                    }
                });
                /* 轴一旋转,然后抬起 */
                S485MotorRun(microPort, 1, 1, 2000, new CommonCallback<String>() {
                    @Override
                    public void statusCallback(String s) {
                        nextProcess(10);
                    }
                });
                /* 轴五抬起 */
                plcMotorRun(5, 200, transportScrewData.getAxle5_2Distance()-2, new CommonCallback<String>() {
                    @Override
                    public void statusCallback(String s) {
                    }
                });

                break;
            case 11:
                S485MotorRun(microPort, 1, 4, 500, new CommonCallback<String>() {
                    @Override
                    public void statusCallback(String s) {
                        nextProcess(11);
                    }
                });
                break;
            case 12:
                /* 轴五回到最高点 */
                plcMotorRun(5, 200, transportScrewData.getAxle5_4Distance(), new CommonCallback<String>() {
                    @Override
                    public void statusCallback(String s) {
                        nextProcess(12);
                    }
                });
                break;

            case 13:
                /* 轴四到拍照点 */
                plcMotorRun(4, 200, transportScrewData.getAxle4_2Distance(), new CommonCallback<String>() {
                    @Override
                    public void statusCallback(String s) {
                        webSocketService.sendMessage("309");

//                        DelayUtil.delayedExecution(3000, new Runnable() {
//                            @Override
//                            public void run() {
//                                nextProcess(13);
//                            }
//                        });
                    }
                });
                break;
            case 14:
                /* 轴四到打孔位 */
                plcMotorRun(4, 200, transportScrewData.getAxle4_3Distance(), new CommonCallback<String>() {
                    @Override
                    public void statusCallback(String s) {
                        nextProcess(14);
                    }
                });

                break;
            case 15:
                nextProcess(15);
                break;
            case 16:
                /* 轴五 下降至打孔位置 */
                S485MotorRun(microPort, 1, 1, 200, new CommonCallback<String>() {
                    @Override
                    public void statusCallback(String s) {

                    }
                });
                plcMotorRun(5, 200, transportScrewData.getAxle5_3Distance(), new CommonCallback<String>() {
                    @Override
                    public void statusCallback(String s) {
                        nextProcess(16);
                    }
                });
                break;
            case 17:
                /*  */
                assemblyBoltService.plcControlMotorJobRun(5, 12.0f, false, true);


                DelayUtil.delayedExecution(14000, new Runnable() {
                    @Override
                    public void run() {
//                        assemblyBoltService.controlMicroMotorRun("3", 1, 4, s ->
//                                log.info("电机接收指令完成"));
                        S485MotorRun("3", 1, 4, 500, new CommonCallback<String>() {
                            @Override
                            public void statusCallback(String s) {

                            }
                        });
                        assemblyBoltService.plcControlMotorJobRun(5, 12.0f, false, false);

                        S485MotorRun("3", 2, 2, 500, new CommonCallback<String>() {
                            @Override
                            public void statusCallback(String s) {
                                nextProcess(17);
                            }
                        });

                    }
                });
                break;
            case 18:
                S485MotorRun("3", 3, 2, 500, new CommonCallback<String>() {
                    @Override
                    public void statusCallback(String s) {
                        plcMotorRun(5, 200, 0, new CommonCallback<String>() {
                            @Override
                            public void statusCallback(String s) {

                            }
                        });

                        DelayUtil.delayedExecution(1000, new Runnable() {
                            @Override
                            public void run() {
                                plcMotorRun(4, 200, 0, new CommonCallback<String>() {
                                    @Override
                                    public void statusCallback(String s) {
                                        log.info("流程运动完毕");
                                        isRunning = false;
                                        doneCount++;
                                        startProcess();
                                    }
                                });
                                assemblyBoltService.plcControlMotorRunY(1,50.f,225.0f);
                                assemblyBoltService.plcControlMotorSerRun(1,true);

                            }
                        });



                    }
                });



        }
    }

    private void checkStart() {
        if (doneCount<1){
            nextProcess(0);
        }else {
            isRunning = false;
            doneCount = 0;
        }
    }

    /**
     * plc控制电机运动
     *
     * @param model
     * @param speed
     * @param distance
     * @param callback
     */
    public void plcMotorRun(int model, int speed, float distance, CommonCallback<String> callback) {
        /* 设置轴不使能 */
        assemblyBoltService.plcControlMotorAbsRun(model, false);
        /* 设置轴的距离和速度 */
        assemblyBoltService.plcControlMotorRunX(model, speed, distance);
        /* 设置轴使能运动 */
        assemblyBoltService.plcControlMotorAbsRun(model, true);
        DelayUtil.delayedExecution(1000, () -> {
            assemblyBoltService.readPlcMotorRunDone(model, aBoolean -> {
                callback.statusCallback("0");
                log.info("轴"+ model + "开始运动完成" + aBoolean);
            });
        });
        log.info("轴"+ model + "开始运动，+ 1000ms");
    }

    /**
     * Micro 485 运动
     *
     * @param port
     * @param model
     * @param cmd
     * @param time
     * @param callback
     */
    public void S485MotorRun(String port, int model, int cmd, int time, CommonCallback<String> callback) {
        assemblyBoltService.controlMicroMotorRun(port, model, cmd, s -> {
            log.info("484 "+model+"完成指令");
        });
        DelayUtil.delayedExecution(time, () -> {
            log.info("当前Micro的"+model+"电机正在运动，延迟了"+ time + "ms");
            callback.statusCallback("0");
        });
    }

    public void cameraResult(float tag, float angle, float distance){
        if (tag == 0 || tag == 1){
            if (angle == 0){
                if (isRunning){
                    nextProcess(13);
                }
                log.info("校准无误,可以打孔");
            } else if (angle != -9999) {
                assemblyBoltService.plcControlMotorSerRun(1,false);
                assemblyBoltService.plcControlMotorRunY(1,50.f,angle * 10.000f);
                assemblyBoltService.plcControlMotorSerRun(1,true);
                DelayUtil.delayedExecution(1000, () -> {
                    if (tag == 0){
                        if (isRunning){
                            nextProcess(13);
                        }
                        log.info("校准无误,可以打孔");
                    } else {
                        webSocketService.sendMessage("309");
                    }
                });
            } else {
                assemblyBoltService.plcControlMotorSerRun(1,false);
                assemblyBoltService.plcControlMotorRunY(1,50.f,50);
                assemblyBoltService.plcControlMotorSerRun(1,true);
                DelayUtil.delayedExecution(1000, () -> {
                    webSocketService.sendMessage("309");
                });
            }
        } else if (tag == 2){
            assemblyBoltService.plcControlMotorAbsRun(4,false);
            assemblyBoltService.plcControlMotorRunX(4, 50.f, distance);
            webSocketService.sendMessage("309");
        } else if (tag == -9999) {
            assemblyBoltService.plcControlMotorAbsRun(4,false);
            assemblyBoltService.plcControlMotorRunX(4, 50.f, distance);
            webSocketService.sendMessage("309");
        }
    }

}
